import { createResolvablePromise } from './common'
import { noCacheUrlFilter } from './miscellaneous'

/**
 * 缓存视频缩略图，base64存到内存中，防止重复请求
 */
const cache = new Map<string, VideoInfo>()
export interface VideoInfo {
  duration: number
  width: number
  height: number
  thumb: string
  url: string
}
export interface AudioInfo {
  duration: number
  url: string
}
export interface ImageInfo {
  width: number
  height: number
  url: string
}
/**
 * 根据视频地址获取视频缩略图
 * @param videoUrl
 * @returns
 */
export function loadVideoInfo(videoUrl: string | File) {
  const uninstallList: Function[] = []
  if (videoUrl instanceof File) {
    videoUrl = URL.createObjectURL(videoUrl)
    uninstallList.push(() => {
      URL.revokeObjectURL(videoUrl as string)
    })
  }
  const cacheData = cache.get(videoUrl)
  if (cacheData) {
    return Promise.resolve(cacheData)
  }
  const [p, resolve, reject] = createResolvablePromise<VideoInfo>()
  let video = document.createElement('video')
  let canvas = document.createElement('canvas')
  video.crossOrigin = 'anonymous'
  video.src = videoUrl
  video.muted = true
  const ctx = canvas.getContext('2d')
  const info: VideoInfo = {
    duration: 0,
    width: 0,
    height: 0,
    thumb: null,
    url: videoUrl,
  }
  const onLoadedmetadata = () => {
    canvas.width = video.videoWidth
    canvas.height = video.videoHeight
    video.currentTime = 0
    info.width = video.videoWidth
    info.height = video.videoHeight
    info.duration = video.duration
  }
  const onError = (e: any) => {
    clear()
    console.error('loadVideoThumb error', e)
    reject(e)
  }
  const onSeeked = () => {
    ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
    const thumbnailUrl = canvas.toDataURL('image/jpeg', 0.6)
    // console.log('url:' + thumbnailUrl)
    info.thumb = thumbnailUrl
    clear()
    resolve(info)
    cache.set(videoUrl, info)
  }
  const clear = () => {
    video.removeEventListener('loadedmetadata', onLoadedmetadata)
    video.removeEventListener('error', onError)
    video.removeEventListener('seeked', onSeeked)
    video.src = ''
    video = null
    canvas = null
    uninstallList.forEach((item) => item())
  }
  video.addEventListener('loadedmetadata', onLoadedmetadata)
  video.addEventListener('error', onError)
  video.addEventListener('seeked', onSeeked)

  return p
}

export function loadAudioInfo(audioUrl: string | File) {
  if (audioUrl instanceof File) {
    audioUrl = URL.createObjectURL(audioUrl)
  }
  const [p, resolve, _] = createResolvablePromise<AudioInfo>()
  let audio = document.createElement('audio')
  audio.crossOrigin = 'anonymous'
  audio.src = audioUrl
  const info: AudioInfo = {
    duration: 0,
    url: audioUrl,
  }
  const onLoadedmetadata = () => {
    info.duration = audio.duration
    // / 1000
    clear()
    resolve(info)
  }
  audio.addEventListener('loadedmetadata', onLoadedmetadata)
  const clear = () => {
    audio.removeEventListener('loadedmetadata', onLoadedmetadata)
    audio.src = ''
    audio = null
  }
  audio.load()
  return p
}
/**
 * 加载图片信息
 * @param imageUrl
 * @returns
 */
export function loadImageInfo(imageUrl: string | File) {
  if (imageUrl instanceof File) {
    imageUrl = URL.createObjectURL(imageUrl)
  }
  const [p, resolve, reject] = createResolvablePromise<ImageInfo>()
  let image = document.createElement('img')
  image.crossOrigin = 'anonymous'
  image.src = noCacheUrlFilter(imageUrl)
  const info: ImageInfo = {
    width: 0,
    height: 0,
    url: imageUrl,
  }
  const onLoad = () => {
    info.width = image.naturalWidth
    info.height = image.naturalHeight
    clear()
    resolve(info)
  }
  const onError = (e: any) => {
    clear()
    console.error('loadImageInfo error', e)
    reject(e)
  }
  image.addEventListener('load', onLoad)
  image.addEventListener('error', onError)
  function clear() {
    image.removeEventListener('load', onLoad)
    image.removeEventListener('error', onError)
    image.src = ''
    image = null
  }

  return p
}
